﻿using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xfm.TagHelpers.Exts;
using Xfm.TagHelpers;

namespace Xfm.TagHelpers
{
    public class MenuTagHelper : TagHelper
    {
        public NavModel Nav { get; set; }

        protected IList<NavNode> Navs => Nav.NavNodes;

        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }
        private string _activeLink;
        private string _activeTitle;
        private string _route;

        public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (ViewContext.ViewData.ContainsKey("NavLink"))
                _activeLink = (string)ViewContext.ViewData["NavLink"];
            else if (ViewContext.ViewData.ContainsKey("NavTitle"))
                _activeTitle = (string)ViewContext.ViewData["NavTitle"];
            else //(string.IsNullOrEmpty(Nav.ActiveLink) && string.IsNullOrEmpty(Nav.ActiveTitle))
            {

                //自动根据Url判断active
                //ViewContext.HttpContext.Request.Path.Value;
                _route = string.Format("/{0}/{1}", ViewContext.RouteData.Values["controller"], ViewContext.RouteData.Values["action"]);
            }
            foreach (var item in Nav.NavNodes)
            {
                GetIsActive(item);
            }

            output.TagName = "ul";
            output.AddClass("nav nav-pills nav-sidebar flex-column");
            output.Attributes.Add("data-widget", "treeview");
            output.Attributes.Add("role", "menu");
            output.Attributes.Add("data-accordion", "false");
            foreach (var item in Navs)
            {
                output.Content.AppendHtml(CreateNavs(item));
            }
            return Task.CompletedTask;
        }
        private bool GetIsActive(NavNode node)
        {
            if (node.Childs == null || node.Childs.Count == 0)
            {
                if (!string.IsNullOrEmpty(_activeLink))
                {
                    if (string.Equals(_activeLink, node.Link, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
                else if (!string.IsNullOrEmpty(_activeTitle))
                {
                    if (string.Equals(_activeTitle, node.Title, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
                else
                {
                    if (node.Link.Contains(_route, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        private TagBuilder CreateNavs(NavNode node)
        {
            TagBuilder li = new TagBuilder("li");
            li.AddCssClass("nav-item");

            TagBuilder a = new TagBuilder("a");
            a.AddCssClass("nav-link");
            a.Attributes.Add("href", node.Link);

            if (GetIsActive(node))
                a.AddCssClass("active");

            TagBuilder i = new TagBuilder("i");
            i.AddCssClass("nav-icon " + node.Icon);

            TagBuilder p = new TagBuilder("p");
            p.InnerHtml.Append(node.Title);



            TagBuilder ul = null;
            if (node.Childs != null && node.Childs.Count > 0)
            {
                ul = new TagBuilder("ul");
                ul.AddCssClass("nav nav-treeview");

                li.AddCssClass("has-treeview");
                var icon = new TagBuilder("i");
                icon.AddCssClass("fas fa-angle-left right");
                p.InnerHtml.AppendHtml(icon);
                if (node.Childs.Any(m => GetIsActive(m)))
                {
                    li.AddCssClass("menu-open");
                    a.AddCssClass("active");
                }

                foreach (var item in node.Childs.OrderBy(m => m.Order))
                {
                    ul.InnerHtml.AppendHtml(CreateNavs(item));
                }
            }

            a.InnerHtml.AppendHtml(i).AppendHtml(p);
            li.InnerHtml.AppendHtml(a);

            if (ul != null)
                li.InnerHtml.AppendHtml(ul);

            return li;
        }
    }
}
